﻿using FirstFloor.ModernUI.Presentation;
using SelElectCalcModernUI.Model;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SelElectCalcModernUI.Lib;

namespace SelElectCalcModernUI.ViewModel.CalcRes
{
    public class SellerResultViewModel
        : NotifyPropertyChanged, IDisposable
    {
        SellerResModel sellerResData;
        CommandBase returnCmd;
        CommandBase exportCmd;
        ObservableCollection<string> sellerResFilters;
        string sellerResFilter;
        ObservableCollection<SellerResSignle> sellerResFiltersRes;
        ObservableCollection<SellerResSignle> sellerResFiltersResDetail;
        ObservableCollection<Model.KeyValuePair<string, double>> totInfo;
        public SellerResModel SellerResData
        {
            get
            {
                if (sellerResData == null)
                    sellerResData = new SellerResModel();
                return sellerResData;
            }
        }
        public CommandBase ReturnCmd
        {
            get
            {
                if (returnCmd == null)
                    returnCmd = new RelayCommand((s) =>
                    {
                        ViewModelLocator.JumpPageEvent("/Pages/HomePage.xaml");
                    });
                return returnCmd;
            }
        }

        public CommandBase ExportCmd
        {
            get
            {
                if (exportCmd == null)
                    exportCmd = new RelayCommand((s) =>
                    {
                        SaveFile();
                    }, (s) => SellerResData.SellerRes != null && SellerResData.SellerRes.Count > 0);
                return exportCmd;
            }
        }

        public ObservableCollection<string> SellerResFilters
        {
            get
            {
                if (sellerResFilters == null)
                    sellerResFilters = new ObservableCollection<string>();
                sellerResFilters.Clear();
                var filters = from c in SellerResData.SellerRes group c.Seller by c.Seller into g select g;
                sellerResFilters.Add("全部");
                foreach (var filter in filters)
                    sellerResFilters.Add(filter.Key);
                return sellerResFilters;
            }
        }

        public string SellerResFilter
        {
            get
            {
                if (string.IsNullOrWhiteSpace(sellerResFilter))
                    sellerResFilter = "全部";
                return sellerResFilter;
            }

            set
            {
                sellerResFilter = value;
                OnPropertyChanged("SellerResFilter");
                OnPropertyChanged("SellerResFiltersRes");
                OnPropertyChanged("SellerResFiltersResDetail");
            }
        }

        public ObservableCollection<SellerResSignle> SellerResFiltersRes
        {
            get
            {
                if (sellerResFiltersRes == null)
                    sellerResFiltersRes = new ObservableCollection<SellerResSignle>();
                sellerResFiltersRes.Clear();
                var res = from c in SellerResData.SellerRes where c.Seller.Equals(sellerResFilter) select c;
                if (sellerResFilter != "全部")
                    foreach (var item in res)
                        sellerResFiltersRes.Add(item);
                else
                    foreach (var item in SellerResData.SellerRes)
                        sellerResFiltersRes.Add(item);
                AddTotAndAvgRow(sellerResFiltersRes);
                CalcTotInfo();
                SellerResData.TotPower =
                    sellerResFiltersRes.Sum((ss) => ss.RealPower);
                SellerResData.TotPrice =
                    sellerResFiltersRes.Sum((ss) => ss.RealPrice * ss.RealPower);
                SellerResData.EveryPrice =
                    SellerResData.TotPrice / SellerResData.TotPower;
                return sellerResFiltersRes;
            }
        }

        public ObservableCollection<SellerResSignle> SellerResFiltersResDetail
        {
            get
            {
                if (sellerResFiltersResDetail == null)
                    sellerResFiltersResDetail = new ObservableCollection<SellerResSignle>();
                sellerResFiltersResDetail.Clear();
                var res = from c in SellerResData.SellerResDetail where c.Seller.Equals(sellerResFilter) select c;
                if (sellerResFilter != "全部")
                    foreach (var item in res)
                        sellerResFiltersResDetail.Add(item);
                else
                    foreach (var item in SellerResData.SellerResDetail)
                        sellerResFiltersResDetail.Add(item);
                AddTotAndAvgRow(sellerResFiltersResDetail);
                return sellerResFiltersResDetail;
            }
        }

        private void CalcTotInfo()
        {
            //throw new NotImplementedException();
            TotInfo[0].Value = ViewModelLocator.FactoryResult.FactoryResData.FactoryRes.Sum(s => s.TotNoBackPrice) - SellerResData.SellerRes.Sum(s => s.TotNoBackPrice);
            TotInfo[1].Value = TotInfo[0].Value * ViewModelLocator.OtherSetting.SellerBackRage / 100;
            TotInfo[2].Value = SellerResData.SellerRes.Sum(s => s.TotNoBackPrice) + SellerResData.SellerRes.Sum(s => s.TotBackPrice);
            TotInfo[3].Value = SellerResData.SellerRes.Sum(s => s.OrgPower * s.OrgPrice) / SellerResData.SellerRes.Sum(s => s.OrgPower) * 1000;
            TotInfo[4].Value = SellerResData.SellerRes.Min(s => s.OrgPrice) * 1000;
            TotInfo[5].Value = SellerResData.SellerRes.Max(s => s.OrgPrice) * 1000;
            TotInfo[6].Value = SellerResData.SellerRes.Sum(s => s.OrgPrice * s.RealPower) / SellerResData.SellerRes.Sum(s => s.RealPower) * 1000;
            TotInfo[7].Value = SellerResData.SellerRes.Min(s => s.RealPrice) * 1000;
            TotInfo[8].Value = SellerResData.SellerRes.Max(s => s.RealPrice) * 1000;
            TotInfo[9].Value = SellerResData.SellerRes.Sum(s => s.RealPrice * s.RealPower) / SellerResData.SellerRes.Sum(s => s.RealPower) * 1000;
            foreach (var item in totInfo)
            {
                item.Value = Math.Round(item.Value, 2);
            }
        }
        public ObservableCollection<Model.KeyValuePair<string, double>> TotInfo
        {
            get
            {
                if (totInfo == null)
                {
                    totInfo = Model.KeyValuePair<string, double>.CreatList("供需中标电量申报价差电费总额（万元）",
"返还给需方（万元）",
"需求侧累计获利（万元）",
"需求侧总平均申报价差（厘 / kWh）",
"需求侧中标售电量最终成交最低申报价差（厘 / kWh）",
"需求侧中标售电量最终成交最高申报价差（厘 / kWh）",
"需求侧中标售电量最终成交平均申报价差（厘 / kWh）",
"需求侧中标售电量最终成交最低结算价差（厘 / kWh）",
"需求侧中标售电量最终成交最高结算价差（厘 / kWh）",
"需求侧中标售电量最终成交平均结算价差（厘 / kWh）");

                }
                return totInfo;
            }
        }

        private static void AddTotAndAvgRow(IList<SellerResSignle> sellers)
        {
            SellerResSignle totRow = new SellerResSignle()
            {
                Seller = "累计值",
                Factory = string.Empty,
                DealTotPerSeat = -1,
                InSeat = -1,
                Times = -1,
                OrgPrice = double.NaN,
                AvgOrgPrice = double.NaN,
                RealPrice = double.NaN,
                AvgBackPrice = double.NaN,
                PerIn = double.NaN,
                DealPer = sellers.Sum(s => s.RealPower) / sellers.Sum(s => s.OrgPower),
                DealTotPer = sellers.Sum(s => s.DealTotPer),
                OrgPower = sellers.Sum(s => s.OrgPower),
                RealPower = sellers.Sum(s => s.RealPower),
                SurplusPower = sellers.Sum(s => s.SurplusPower),
                TotBackPrice = sellers.Sum(s => s.TotBackPrice),
                TotDifPrice = sellers.Sum(s => s.TotDifPrice),
                TotIn = sellers.Sum(s => s.TotIn),
                TotNoBackPrice = sellers.Sum(s => s.TotNoBackPrice),
                TotPrice = sellers.Sum(s => s.TotPrice),
                TotPriceRange = sellers.Sum(s => s.TotPriceRange)
            };
            SellerResSignle avgRow = new SellerResSignle()
            {
                Seller = "平均值",
                Factory = string.Empty,
                DealTotPerSeat = -1,
                InSeat = -1,
                Times = -1,
                OrgPrice = sellers.Sum(s => s.OrgPower * s.OrgPrice) / totRow.OrgPower,
                AvgOrgPrice = sellers.Sum(s => s.RealPower * s.OrgPrice) / totRow.RealPower,
                RealPrice = (totRow.TotBackPrice - totRow.TotNoBackPrice) / totRow.RealPower,
                AvgBackPrice = totRow.TotBackPrice / totRow.RealPower,
                PerIn = double.NaN,
                DealPer = double.NaN,
                DealTotPer = double.NaN,
                OrgPower = double.NaN,
                RealPower = double.NaN,
                SurplusPower = double.NaN,
                TotBackPrice = double.NaN,
                TotDifPrice = double.NaN,
                TotIn = double.NaN,
                TotNoBackPrice = double.NaN,
                TotPrice = double.NaN,
                TotPriceRange = double.NaN
            };
            sellers.Add(totRow);
            sellers.Add(avgRow);
        }

        private void SaveFile()
        {
            var stream = ViewModelLocator.SaveFileEvent("csv");
            if (stream == null)
                return;
            System.IO.StreamWriter tr = new System.IO.StreamWriter(stream, Encoding.Default);
            SaveFileString(tr);
            tr.Flush();
            tr.Close();
        }

        public void SaveFileString(System.IO.StreamWriter tr)
        {
            tr.WriteLine("需求方统计");
            tr.WriteLine("需求侧,(总)申购电量(万kWh),(平均)申购价差(厘/kWh),(总)中标购电量(万kWh)," +
                "(平均)中标购电量申购价差(厘/kWh),(总)中标购电量申购价差电费(万元),(总)中标购电量返还需方价差电费(万元)," +
                "(平均)中标购电量返还需方价差(厘/kWh),(平均)中标购电量最终成交结算价差(厘/kWh),(平均)中标购电量单位收益(厘/kWh)," +
                "(平均)中标购电量单位收益排名,(总)中标购电量本次总收益(万元),(总)各方中标购电量占各方申购购电量比例(%)," +
                "(总)各方中标购电量占总允许成交电量比例(%),(总)各方中标购电量占总允许成交电量比例 排名,(总)各方剩余电量(万Kwh)," +
                "(总)各方中标购电量占总成交电费比例(%),(总)各方中标电费(万元),(总)各方差价电费(万元)");
            List<SellerResSignle> temp = (from c in SellerResData.SellerRes select c).ToList();
            AddTotAndAvgRow(temp);
            foreach (var se in temp)
            {
                tr.WriteLine(se.Seller + "," + se.OrgPower.GetString() + "," + (se.OrgPrice * 1000).GetString() + "," + se.RealPower.GetString() + "," + (se.AvgOrgPrice * 1000).GetString()
                    + "," + se.TotNoBackPrice.GetString() + "," + se.TotBackPrice.GetString() + "," + (se.AvgBackPrice * 1000).GetString() + "," + (se.RealPrice * 1000).GetString()
                    + "," + (se.PerIn * 1000).GetString() + "," + se.InSeat.GetString() + "," + se.TotIn.GetString() + "," + (se.DealPer * 100).GetString() + "," + (se.DealTotPer * 100).GetString()
                    + "," + se.DealTotPerSeat.GetString() + "," + se.SurplusPower.GetString() + "," + (se.TotPriceRange * 100).GetString() + "," + se.TotPrice.GetString() + "," 
                    + se.TotDifPrice.GetString());
            }
            tr.WriteLine("需求方价次统计");
            tr.WriteLine("需求侧,报价次数,(总)申购电量(万kWh),(平均)申购价差(厘/kWh),(总)中标购电量(万kWh)," +
                "(平均)中标购电量申购价差(厘/kWh),(总)中标购电量申购价差电费(万元),(总)中标购电量返还需方价差电费(万元)," +
                "(平均)中标购电量返还需方价差(厘/kWh),(平均)中标购电量最终成交结算价差(厘/kWh),(平均)中标购电量单位收益(厘/kWh)," +
                "(平均)中标购电量单位收益排名,(总)中标购电量本次总收益(万元),(总)各方中标购电量占各方申购购电量比例(%)," +
                "(总)各方中标购电量占总允许成交电量比例(%),(总)各方中标购电量占总允许成交电量比例 排名,(总)各方剩余电量(万Kwh)," +
                "(总)各方中标购电量占总成交电费比例(%),(总)各方中标电费(万元),(总)各方差价电费(万元)");
            temp = (from c in SellerResData.SellerResDetail select c).ToList();
            AddTotAndAvgRow(temp);
            foreach (var se in temp)
            {
                tr.WriteLine(se.Seller + "," + se.Times.GetString() + "," + se.OrgPower.GetString() + "," + (se.OrgPrice * 1000).GetString() + "," + se.RealPower.GetString() + "," + (se.AvgOrgPrice * 1000).GetString()
                    + "," + se.TotNoBackPrice.GetString() + "," + se.TotBackPrice.GetString() + "," + (se.AvgBackPrice * 1000).GetString() + "," + (se.RealPrice * 1000).GetString()
                    + "," + (se.PerIn * 1000).GetString() + "," + se.InSeat.GetString() + "," + se.TotIn.GetString() + "," + (se.DealPer * 100).GetString() + "," + (se.DealTotPer * 100).GetString()
                    + "," + se.DealTotPerSeat.GetString() + "," + se.SurplusPower.GetString() + "," + (se.TotPriceRange * 100).GetString() + "," + se.TotPrice.GetString() + ","
                    + se.TotDifPrice.GetString());
            }
            CalcTotInfo();
            foreach (var info in totInfo)
            {
                tr.WriteLine(info.Key + "," + info.Value);
            }
        }

        public void Dispose()
        {
        }
    }
}
